import React from 'react';

export interface TreeTableColumn<T = Record<string, unknown>> {
  key: string;
  title: React.ReactNode;
  dataIndex: string;
  width?: number | string;
  fixed?: 'left' | 'right' | boolean;
  align?: 'left' | 'center' | 'right';
  sorter?: boolean | ((a: T, b: T) => number);
  sortOrder?: 'ascend' | 'descend' | null;
  filters?: Array<{ text: string; value: string | number }>;
  filterMultiple?: boolean;
  filteredValue?: (string | number)[];
  render?: (value: unknown, record: T, index: number, level: number) => React.ReactNode;
  ellipsis?: boolean;
  hidden?: boolean;
  description?: string;
}

export interface TreeTableAction<T = Record<string, unknown>> {
  key: string;
  label: string;
  icon?: React.ReactNode;
  danger?: boolean;
  disabled?: boolean;
  onClick: (record: T) => void;
  visible?: (record: T) => boolean;
}

export interface TreeTableNode<T = Record<string, unknown>> {
  id: string | number;
  children?: TreeTableNode<T>[];
  level?: number;
  expanded?: boolean;
  parentId?: string | number;
  [key: string]: unknown;
}

export interface TreeTablePagination {
  current: number;
  pageSize: number;
  total: number;
  showSizeChanger?: boolean;
  showQuickJumper?: boolean;
  showTotal?: (total: number, range: [number, number]) => React.ReactNode;
  pageSizeOptions?: string[];
  onChange?: (page: number, pageSize: number) => void;
}

export interface TreeTableSearchField {
  key: string;
  label: string;
  placeholder?: string;
  type: 'input' | 'select' | 'date' | 'number' | 'treeSelect';
  options?: Array<{ label: string; value: string | number }>;
  allowClear?: boolean;
}

export interface TreeTableProps<T = Record<string, unknown>> {
  columns: TreeTableColumn<T>[];
  data: TreeTableNode<T>[];
  loading?: boolean;
  rowKey?: string | ((record: T) => string);
  pagination?: false | TreeTablePagination;
  bordered?: boolean;
  size?: 'small' | 'middle' | 'large';
  showHeader?: boolean;
  scroll?: { x?: number | string; y?: number | string };
  title?: () => React.ReactNode;
  footer?: () => React.ReactNode;
  searchFields?: TreeTableSearchField[];
  onSearch?: (params: Record<string, unknown>) => void;
  onExport?: (format: 'csv' | 'excel' | 'pdf') => void;
  batchActions?: TreeTableAction<T>[];
  nodeActions?: TreeTableAction<T>[];
  defaultExpandAll?: boolean;
  defaultExpandedKeys?: (string | number)[];
  indentSize?: number;
  showExpandColumn?: boolean;
  refresh?: () => void;
  extra?: React.ReactNode;
  rowClassName?: (record: T, index: number, level: number) => string;
  onRow?: (record: T, index: number, level: number) => Record<string, unknown>;
  onChange?: (pagination: TreeTablePagination, filters: Record<string, unknown>, sorter: unknown) => void;
  onExpand?: (expanded: boolean, record: T) => void;
  onExpandedRowsChange?: (expandedRowKeys: (string | number)[]) => void;
  expandedRowKeys?: (string | number)[];

  columnSettings?: {
    enabled?: boolean;
    defaultVisibleColumns?: string[];
    onColumnsChange?: (visibleColumns: string[]) => void;
  };

  stickySettings?: {
    enabled?: boolean;
    header?: boolean;
    search?: boolean;
    offsetTop?: number;
    onHeaderChange?: (enabled: boolean) => void;
  };

  columnPinning?: {
    enabled?: boolean;
    defaultPinnedColumns?: {
      left?: string[];
      right?: string[];
    };
    onPinnedColumnsChange?: (pinnedColumns: { left?: string[]; right?: string[] }) => void;
  };
}

export interface TreeTableState {
  searchText: string;
  searchParams: Record<string, unknown>;
  filteredInfo: Record<string, unknown>;
  sortedInfo: unknown;
  selectedRowKeys: React.Key[];
  selectedRows: TreeTableNode[];
  visibleColumns: string[];
  columnSettingsVisible: boolean;
  pinnedColumns: {
    left?: string[];
    right?: string[];
  };
  columnPinningVisible: boolean;
  expandedRowKeys: (string | number)[];
}

export type TreeTableInstance = {
  refresh: () => void;
  resetSearch: () => void;
  getSelectedRows: () => TreeTableNode[];
  getSearchParams: () => Record<string, unknown>;
  expandAll: () => void;
  collapseAll: () => void;
  expandNode: (key: string | number) => void;
  collapseNode: (key: string | number) => void;
  getExpandedKeys: () => (string | number)[];
};